package rs.mbs2.epics.server.servlet;

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.imageio.ImageIO;
import javax.mail.Session;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;

import rs.mbs2.epics.server.entity.Album;
import rs.mbs2.epics.server.entity.Photo;
import rs.mbs2.epics.server.entity.User;
import rs.mbs2.epics.server.servlet.util.Emailer;
import rs.mbs2.epics.server.servlet.util.ImageUtil;
import rs.mbs2.epics.server.servlet.util.Validation;
import rs.mbs2.epics.server.session.dao.localinterface.AlbumDaoLocal;
import rs.mbs2.epics.server.session.dao.localinterface.PhotoDaoLocal;

@SuppressWarnings("serial")
public class UploadImageController extends HttpServlet {

	private static Logger log = Logger.getLogger(UploadImageController.class);
	public static final String folderFilesOnServerName = "Files";
	public static final String thumbnailsFolderOnServerName = "thumbnails";
	private Integer photoId = null;
	
	@EJB
	private PhotoDaoLocal photoDao;
	
	@EJB
	private AlbumDaoLocal albumDao;
	
	@Resource(name="Mail")
	private Session session;
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {

			String title = null;
			String description = null;
			boolean publicVisible = false;
			boolean tagsAllowed = false;
			boolean notesAllowed = false;
			boolean commentsAllowed = false;
			Integer albumId = null;

			@SuppressWarnings("unchecked")
			List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);

			for (FileItem item : items) {
				if (item.isFormField()) {

					boolean isValid = true;

					if(item.getFieldName().equals("title")) {
						title = item.getString();
						isValid = Validation.validateString(title);
					} else if(item.getFieldName().equals("description")) {
						description = item.getString();
						isValid = Validation.validateString(description);
					} else if(item.getFieldName().equals("public")) {
						publicVisible = item.getString() != null;	// ako nije štiklirano biće true
					} else if(item.getFieldName().equals("tags_allowed")) {
						tagsAllowed = item.getString() != null;
					} else if(item.getFieldName().equals("notes_allowed")) {
						notesAllowed = item.getString() != null;
					} else if(item.getFieldName().equals("comments_allowed")) {
						commentsAllowed = item.getString() != null;
					} else if(item.getFieldName().equals("albums")) {
						String selectedAlbumId = item.getString();
						isValid = Validation.validateString(selectedAlbumId);
						System.out.println("Album id: " + selectedAlbumId);
						albumId = Integer.parseInt(item.getString());
					}

					if(!isValid) {
						log.error(new Date() + "Greška pri validaciji parametara, ili nije selektovan album.");
						response.sendRedirect(response.encodeRedirectURL("./uploadPhoto.jsp"));
					}

				} 
			}

			for (FileItem item : items) {
				if (!item.isFormField()) {	// fajl (slika)

					String fileName = item.getName();
					System.out.println("Ime slike za upload: " + fileName);

					if(!fileName.equals("")) {	// ako je odabrana neka slika za upload
						
						User loggedUser = (User) request.getSession().getAttribute("user");
						if(loggedUser == null) {
							response.sendRedirect("login.jsp");
							return;
						}
						
						Album selectedAlbum = albumDao.findById(albumId);
						
						int userId = loggedUser.getId();
						// /Files/1
						String userFolderPath = getServletContext().getRealPath("") + "/" + folderFilesOnServerName + "/" +  userId;
						String folderName = selectedAlbum.getId().toString();	// id od albuma je ima foldera

						// kreira direktorijume: /Files/1/profileImage/
						// vrati putanju:  /Files/1/profileImage/imeSlike.jpg
						String filePath = ImageUtil.createImagePaths(userFolderPath, folderName, fileName);

						File fileToUpload = new File(filePath);		// kreira fajl: /Files/1/profileImage/imeSlike.jpg
						item.write(fileToUpload);

						//BufferedImage sourceImage = ImageIO.read(new File(filePath));
						BufferedImage image = ImageIO.read(fileToUpload);
						BufferedImage thumbnail = ImageUtil.getThumbnail(filePath, image);
						// kreira direktorijume: /Files/1/profileImage/thumbnails/
						// vrati putanju: /Files/1/profileImage/thumbnails/imeSlike.jpg
						String thumbnailFilePath = ImageUtil.getThumbnailPath(userFolderPath, folderName, fileName);

						File thumbnailImageFile = new File(thumbnailFilePath);	// kreira fajl: /Files/1/profileImage/thumbnails/imeSlike.jpg
						ImageIO.write(thumbnail, "jpg", thumbnailImageFile);

						int width = image.getWidth();
						int height = image.getHeight();
						byte[] imageBytes = ((DataBufferByte) image.getData().getDataBuffer()).getData();
						Long size = new Long(imageBytes.length);
						String relativeFilePath = folderFilesOnServerName + "/" + userId + "/" + folderName + "/" + fileName;
						String relativeThumbnailPath = folderFilesOnServerName + "/" + userId + "/" + folderName + "/" + thumbnailsFolderOnServerName + "/" + fileName;

						/*
						 * 	public Photo(String location, Integer width, Integer height, Long size,
			Date uploadDate, String title, String description,
			Boolean publiclyAvailable, Boolean tagsAllowed, Boolean notesAllowed,
			Boolean commentsAllowed, Integer averageRating, String thumbnailLocation) {
						*/
						
						Photo photo = new Photo(relativeFilePath,
								width,
								height,
								size,
								new Date(),
								title,
								description,
								publicVisible,
								tagsAllowed,
								notesAllowed,
								commentsAllowed,
								new Double(0.0),
								relativeThumbnailPath);
								
						photoDao.persist(photo);
						selectedAlbum.getPhotos().add(photo);
						albumDao.merge(selectedAlbum);
						
						this.photoId = photo.getId();
						
						Emailer emailer = new Emailer();
						Set<User> followersTemp = loggedUser.getFollowers();
						if(!followersTemp.isEmpty()){
							List<User> followers = new ArrayList<>();
							followers.addAll(followersTemp);
							for(User f : followers) {
								if(f.getEmailNotifications()) {
									emailer.sendMessage(session, "mbs2testmail@gmail.com", f.getEmailAddress());
								}
							}
						}
						
					} else {
						String errClass = "UploadImageController.doGet()";
						log.error(errClass);
					}
					

					break;	// ocekuje se samo jedna slika, nema potrebe da se dalje prolazi kroz polja na formi.
				}
			}

			//getServletContext().getRequestDispatcher("/HomeController").forward(request, response);
			
			getServletContext().getRequestDispatcher("/ViewPhotoController?id=" + photoId).forward(request, response);
			
		} catch (IOException e) {
			log.error((new Date()).toString() + e);
			e.printStackTrace();
		} catch (FileUploadException e) {
			log.error((new Date()).toString() + e);
			e.printStackTrace();
		} catch (ParseException e) {
			log.error((new Date()).toString() + e);
			e.printStackTrace();
		} catch (Exception e) {
			log.error((new Date()).toString() + e);
			e.printStackTrace();
		}
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
	
}
